//#pragma comment (lib, "glaux.lib")
#pragma comment(lib, "urlmon.lib")
#using <system.drawing.dll>

#include "image.h"

#include <windows.h>		// Header File For Windows
#include <gl\gl.h>			// Header File For The OpenGL32 Library
#include <gl\glu.h>			// Header File For The GLu32 Library
#include <gl\glaux.h>		// Header File For The Glaux Library

#include <direct.h> // for getcwd
#include <stdlib.h>// for MAX_PATH
#include <iostream>
#include <fstream>
#include <vector>

#include <urlmon.h>
#include < vcclr.h >

using namespace System::Runtime::InteropServices;
using namespace System::Windows::Forms;
using namespace System;
using namespace System::Drawing;
using namespace System::Drawing::Imaging;

class picture
{
	public:
		GLfloat	xrot;				// X Rotation ( NEW )
		GLfloat	yrot;				// Y Rotation ( NEW )
		GLfloat	zrot;				// Z Rotation ( NEW )
		GLuint *texture;			// textures array
		
		std::vector <image*>			images;

public:

	picture()
	{ 
		images.clear(); 
		texture = NULL;
	}

	~picture()
	{
		//delete all pictures
		images.clear(); 
		texture = NULL;
	}

	char *convert(String^ str)
	{
		pin_ptr<const wchar_t> wch = PtrToStringChars(str);
	    size_t convertedChars = 0;
	    size_t  sizeInBytes = ((str->Length + 1) * 2);
	    errno_t err = 0;
	    char *ch = (char *)malloc(sizeInBytes);

	    err = wcstombs_s(&convertedChars, ch, sizeInBytes, wch, sizeInBytes);
		if (err != 0){ std::cerr << "wcstombs_s  failed!\n"; }
		return ch;
	}

	//Remove all files from C:\\webCubeTemp
	void clearAll()
	{
		images.clear(); 
		texture = NULL;
	}

	void addImages(HtmlElementCollection^ list)
	{	
		std::ofstream fout;
		fout.open("check.txt", std::ios::app);
		fout << "=-==-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n";
	    for(int i = 0; i < list->Count; i++)
		{
			HtmlElement^ a = list[i];
			String^ s2 = a->GetAttribute("src");

			int p = (s2->LastIndexOf("/")) + 1;
			String^ fn = s2->Substring(p);

			IntPtr url = Marshal::StringToHGlobalUni(s2);
			String^ s3 = s3->Concat("C:\\webCubeTemp\\", fn);
			IntPtr filename = Marshal::StringToHGlobalUni(s3);
			//Test((LPCWSTR)ptr.ToPointer());
			//Download file		
			fout << "Saving: " << (LPCWSTR)url.ToPointer() << " to " << (LPCWSTR)filename.ToPointer() << std::endl;
	    
			HRESULT hr = URLDownloadToFile ( NULL, (LPCWSTR)url.ToPointer(), (LPCWSTR)filename.ToPointer(), 0, NULL );
			//Convert and load into openGL
			image* im = new image(s3);
			images.push_back(im);
			fout << "image pushed\n";
	    	
		}
	    fout.close();
	}

	/************* LoadGLTextures *****************************/
	// Load Bitmaps And Convert To Textures
	GLvoid LoadGLTextures()									// Load Bitmaps And Convert To Textures
	{
		int LEN = images.size();
		std::ofstream myfile;
		myfile.open("textureinfo.txt");
		myfile << "number of textures = " << LEN << std::endl;
		myfile.close();
		if(LEN == 0) return;

		AUX_RGBImageRec *TextureImage[50];
		memset(TextureImage,0,sizeof(void *)*LEN);				// Set The Pointer To NULL

		for(int i = 0; i < LEN; i++)
		{
			image* im = images.at(i);
			TextureImage[i] = im->getImage();
		}

		//we want to build two textures, and we want the texture to be stored in texture[0], texture[1]
		texture = new GLuint[LEN];
		glGenTextures(LEN, &texture[0]);

		// Loop Through All The Textures
		for(int loop=0; loop < LEN; loop++)	
		{
			// Build All The Textures
			glBindTexture(GL_TEXTURE_2D, texture[loop]);
			//The next two lines tell OpenGL what type of filtering to use when the image 
			//is larger (GL_TEXTURE_MAG_FILTER) or stretched on the screen than the original 
			//texture, or when it's smaller (GL_TEXTURE_MIN_FILTER) on the screen than the actual texture.
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
			// Generate The Texture
			glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);
		}

		/*//The following lines of code check to see if the bitmap data we loaded to build our textures is using up ram. If it is, the ram is freed. 
		for(int loop=0; loop < LEN; loop++)
		{
	        if(TextureImage[loop])						// If Texture Exists
			{
				if(TextureImage[loop]->data)			// If Texture Image Exists
				{
					free(TextureImage[loop]->data);		// Free The Texture Image Memory
				}
				free(TextureImage[loop]);			// Free The Image Structure
			}
		}*/								// Return The Status
	}

////DRAW THE SCENE//////////

	/*GLvoid DrawGLSceneCube(GLvoid)
	{
		glBindTexture(GL_TEXTURE_2D, texture[0]);

		glBegin(GL_QUADS);
			// Front Face
			//glNormal3f( 0.0f, 0.0f, 1.0f);
			glTexCoord2f(0.0f, 1.0f); 
			glVertex3f(-1.0f,  1.0f,  0.0f);
			glTexCoord2f(1.0f, 1.0f); 
			glVertex3f( 1.0f,  1.0f,  0.0f);
			glTexCoord2f(1.0f, 0.0f); 
			glVertex3f( 1.0f, -1.0f,  0.0f);
			glTexCoord2f(0.0f, 0.0f); 
			glVertex3f(-1.0f, -1.0f,  0.0f);
		glEnd();
	}*/

	GLvoid DrawGLScene(GLvoid)
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear The Screen And The Depth Buffer
		//glLoadIdentity();										// Reset The View
		
		int LEN = images.size();
		if(LEN == 0) return;
		for(int x = 0; x < LEN; x++)
		{
			glBindTexture(GL_TEXTURE_2D, texture[x]);
			glBegin(GL_QUADS);

				// Front Face
				//glNormal3f( 0.0f, 0.0f, 1.0f);
				glTexCoord2f(0.0f, 1.0f); 
				//glVertex3f(-1.0f,  1.0f,  0.0f);
				glVertex3f(float(x-2), float(x-2), float(x-1));
				glTexCoord2f(1.0f, 1.0f); 
				//glVertex3f( 1.0f,  1.0f,  0.0f);
				glVertex3f(float(x-1), float(x-2), float(x-1));
				glTexCoord2f(1.0f, 0.0f); 
				//glVertex3f( 1.0f, -1.0f,  0.0f);
				glVertex3f(float(x-1), float(x-1), float(x-1));
				glTexCoord2f(0.0f, 0.0f); 
				//glVertex3f(-1.0f, -1.0f,  0.0f);
				glVertex3f(float(x-2), float(x-2), float(x-1));
			glEnd();

			//glTexCoord2f(0.0f, 0.0f); glVertex3f(float(x), float(x), 0.0f);
			//glTexCoord2f(1.0f, 0.0f); glVertex3f(float(x+1), float(x), 0.0f);
			//glTexCoord2f(1.0f, 1.0f); glVertex3f(float(x+1), float(x+1), 0.0f);
			//glTexCoord2f(0.0f, 1.0f); glVertex3f(float(x), float(x+1), 0.0f);
			//glEnd();
		}
	}

//Depreciated!!!!!!!!!!!!!!!!!!!!
int draw_tiles(GLvoid)
{
	int map[10][10] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
						   {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
						   {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
						   {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
						   {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
						   {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
						   {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
						   {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
						   {1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
						   {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
						   };
  int tile;
	for (int y = 0; y < 10; y++)
  {
    for (int x = 0; x < 10; x++)
    {
		tile = map[y][x];
		glBindTexture(GL_TEXTURE_2D, texture[tile]);
								// Keep Going
		 glBegin(GL_QUADS);

    glTexCoord2f(0.0f, 0.0f); glVertex3f(float(x), float(y), 0.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(float(x + 1), float(y), 0.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(float(x + 1), float(y + 1), 0.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(float(x), float(y + 1), 0.0f);
    glEnd();

    }
  }
  return (1);
}

};